package com.trkj.service;


import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSON;
import com.trkj.dao.DeptDAO;
import com.trkj.dao.EmpDAO;
import com.trkj.dao.MenuroleDAO;
import com.trkj.dao.PermissionDAO;
import com.trkj.pojo.Dept;
import com.trkj.pojo.Emp;
import com.trkj.pojo.Menurole;
import com.trkj.pojo.Permission;
import com.trkj.utils.DataGrid;
import com.trkj.vo.DeptVo;
import com.trkj.vo.EmpVo;
import com.trkj.vo.FindMenuroleVo;
import com.trkj.vo.PermissionsTypeVo;
import com.trkj.vo.PermissionsVo;
/**
 * 菜单角色服务层
 * @author 吴山峰
 *
 */
@Service
@Transactional
public class MenuRoleService {
	@Autowired
	MenuroleDAO menuRoleDAO;
	@Autowired
	PermissionDAO permissionDAO;
	@Autowired
	EmpDAO empDAO;
	@Autowired
	DeptDAO deptDAO;
	/**
	 * 查询所有菜单角色||根据条件查询部分菜单角色
	 */
	public DataGrid queryMenuRoleInfo(String menuRoleName, Integer page, Integer rows, String sort, String order) {
		Pageable pageable = new PageRequest(page-1, rows, new Sort(Sort.Direction.fromStringOrNull(order), sort));
		Page<Menurole> pageSelect = pageSelect(menuRoleName, pageable);
		List<Menurole> content = pageSelect.getContent();
		//这里不需要查询Menurole对象的关联对象，所有需要用到vo层
		List<FindMenuroleVo> roleset = new ArrayList<>();
		for (Menurole menurole : content) {
			FindMenuroleVo f = new FindMenuroleVo();
			f.setRoleDesc(menurole.getRoleDesc());
			f.setRoleId(menurole.getRoleId());
			f.setRoleName(menurole.getRoleName());
			f.setRoleState(menurole.getRoleState());
			roleset.add(f);
		}
		return new DataGrid(pageSelect.getTotalElements(), roleset);
	}

	/**
	 * 创建分页查询
	 */
	public Page<Menurole> pageSelect(String menuRoleName, Pageable pageable) {
		Page<Menurole> resultPage = menuRoleDAO.findAll(new Specification<Menurole>() {
			@Override
			public Predicate toPredicate(Root<Menurole> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
				Predicate p1=null;
				if (menuRoleName != null&&menuRoleName.length() > 0) {
					p1 = cb.like(root.get("roleName"), "%"+menuRoleName+"%");
					return cb.or(p1);
				} else {
					return null;
				}

			}
		}, pageable);
		return resultPage;
	}
	
	/**
	 * 编辑/新建 菜单角色
	 */
	public boolean editMenuRole(Menurole menurole) {
		try {
			menuRoleDAO.save(menurole);
			return true;
		} catch (Exception e) {
			e.printStackTrace();
			System.out.println("更改用户信息错误！");
			return false;
		}
	}
	/**
	 * 删除菜单角色,要先把与角色关联的用户和权限删除，在删除菜单角色
	 */
	public boolean removeMenuRole(Menurole menurole) {
		try {
		Menurole menurole2 = menuRoleDAO.findByRoleId(menurole.getRoleId());
		if(null != menurole2.getPermissions()) {
			//清除和权限的关联
			menurole2.getPermissions().clear();
		}
		//删除方法一
		/*List<Emp> emps = empDAO.findAll();
		//清除和用户的关联,由于用户才是用户和角色关系维护端，所以通过用户去删除角色
		if(null != emps) {
			for (Emp emp : emps) {
				if(null != emp.getMenuroles()) {
				emp.getMenuroles().remove(menurole2);
				//先保存一下
				empDAO.save(emp);
				}
			}
		}*/
		//删除方法二
		if(null != menurole2.getEmps()) {
			//清除和权限的关联
			List<Emp> emps = menurole2.getEmps();
			for (Emp emp : emps) {
				emp.getMenuroles().remove(menurole2);
				empDAO.save(emp);
			}
		}
			//删除菜单角色
		menuRoleDAO.delete(menurole2);
		return true;
		} catch (Exception e) {
			e.printStackTrace();
			System.out.println("删除菜单角色失败！");
			return false;
		}
	}
	/**
	 * 根据id查询角色拥有的权限
	 * @return 
	 */
	public Object queryAllFunctionByRoleId(Integer roleid) {
		List<PermissionsTypeVo> listpt = new ArrayList<>();
		Integer id=0;
		//所有的
		List<Object[]> listo = permissionDAO.queryPermissionByRoleId(roleid);
		Set<String> ptname = new HashSet<>();
		//找出不重复所有的名称放到ptname 不重复set集合中
		for (Object[] objects : listo) {
			for (int i = 0; i < objects.length; i++) {
				ptname.add((String)objects[1]);
			}
		}
		//遍历set集合
		for (String string : ptname) {
			List<PermissionsVo> listpv = new ArrayList<>();
			//创建PermissionsTypeVo对象并加入名称，然后再加入 permissionsVo对象
			PermissionsTypeVo permissionsTypeVo = new PermissionsTypeVo();
			permissionsTypeVo.setPerid(id++);
			permissionsTypeVo.setPername(string);
			
			/*f.per_id,f.per_name,f.per_funurl,f.per_menuurl,f.per_blockurl,boolean*/
			for (Object[] objects : listo) {
					if(objects[1].equals(string)) {
						String funname = null;
						//创建permissionsVo对象并初始化
						PermissionsVo permissionsVo = new PermissionsVo();
						permissionsVo.setPerid((Integer)objects[0]);
						if (objects[2]!=null && (objects[2]+"").length()>0) {
							funname = objects[2]+"";
						} else if (objects[3]!=null && (objects[3]+"").length()>0) {
							funname = objects[3]+"";
						} else if (objects[4]!=null && (objects[4]+"").length()>0) {
							funname = objects[4]+"";
						}
						permissionsVo.setPername(funname);
						permissionsVo.setSelected(objects[5]!=null);
						//将permissionsVo加入到集合中，以便后面被PermissionsTypeVo加入
						listpv.add(permissionsVo);
					
				}
			}
			//将List<PermissionsVo>加入到permissionsTypeVo中
			permissionsTypeVo.setList(listpv);
			//将permissionsTypeVo加入到List<PermissionsTypeVo>中
			listpt.add(permissionsTypeVo);
		} 
		return JSON.toJSON(listpt);
	}
	/**
	 * 根据id查询角色所拥有的用户
	 */
	public Object queryEmpByRoleid(Integer roleid) {
		List<Dept> depts = deptDAO.queryAllDept();
		List<DeptVo> deptVos = new ArrayList<>();
		for (Dept dept : depts) {
			//根据部门id和角色id查询该部门下员工是否有这个角色
			List<Object[]> objects = empDAO.findEmpRoleByEmpIdAndDeotId(roleid, dept.getDeptId());
			List<EmpVo> empVos = new ArrayList<>();
			for (Object[] objects2 : objects) {
				EmpVo empVo = new EmpVo();
				empVo.setEmpid((int)objects2[0]);
				empVo.setEmpname(objects2[1]+"");
				empVo.setIscheck(objects2[2]!=null);
				empVos.add(empVo);
			}
			//重新封装到deptvo
			DeptVo deptVo = new DeptVo();
			deptVo.setDeptId(dept.getDeptId());
			deptVo.setDeptname(dept.getDeptName());
			deptVo.setEmps(empVos);
			deptVos.add(deptVo);
		}
		return JSON.toJSON(deptVos);
	}
	/**
	 * 给角色分配权限
	 */
	public boolean giveMenuRolePermissions(Integer roleid, String perids) {
		try {
		String[] funids=null; 
		if(perids!=null && perids.length()>0) {
			funids = perids.split(",");
		}
		Menurole menurole = menuRoleDAO.findByRoleId(roleid);
		if(menurole.getPermissions()==null) {
			menurole.setPermissions(new ArrayList<>());
		}
		menurole.getPermissions().clear();
		if(funids!=null) {
			for (int i = 0; i < funids.length; i++) {
				Permission permission = permissionDAO.findOne(Integer.parseInt(funids[i]));
				menuRoleDAO.flush();
				menurole.getPermissions().add(permission);
			}
		}
		menuRoleDAO.save(menurole);
        	return true;
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}
	/**
	 * 给角色指定用户
	 * 由于用户才是关系的维护端,所以这里还是以用户为主。
	 * @return 
	 */
	public boolean giveMenuRoleEmp(Integer roleid, String Empids) {
		try {
			String[] arrempid = null;
			if(Empids!=null) {
				arrempid = Empids.split(",");
			}
			//先找到这个角色
			Menurole menurole = menuRoleDAO.findByRoleId(roleid);
			//先清除role中的所有用户
			if(null != menurole.getEmps()) {
				for (Emp emp : menurole.getEmps()) {
					emp.getMenuroles().remove(menurole);
				}
			}
			//再为role重新分配用户
			if (arrempid != null) {
				for (String empid:arrempid) {
					Emp emp = empDAO.findOne(Integer.parseInt(empid));
					if (emp.getMenuroles()==null) {
						emp.setMenuroles(new ArrayList<>());
					}
					emp.getMenuroles().add(menurole);
				}
			}
			return true;
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}
	/**
	 * 菜单角色的权限详细信息
	 */
	public List<PermissionsVo> findMenuRolePerDesc(Integer roleid) {
		//1.角色所拥有的权限
		Menurole menurole = menuRoleDAO.findByRoleId(roleid);
		List<Permission> permissions = menurole.getPermissions();
		List<PermissionsVo> permissionsVos = new ArrayList<>();
		for (Permission permission: permissions) {
			PermissionsVo permissionsVo = new PermissionsVo();
			permissionsVo.setPerid(permission.getPerId());
			if(null != permission.getPerMenuurl() && permission.getPerMenuurl().length()>0) {
				System.out.println(permission.getPerMenuurl());
				permissionsVo.setPername(permission.getPerMenuurl());
				permissionsVos.add(permissionsVo);
			} else if (null!=permission.getPerFunurl() && permission.getPerFunurl().length()>0) {
				System.out.println(permission.getPerFunurl());
				permissionsVo.setPername(permission.getPerFunurl());
				permissionsVos.add(permissionsVo);
			} else if (null!=permission.getPerBlockurl() && permission.getPerBlockurl().length()>0) {
				System.out.println(permission.getPerBlockurl());
				permissionsVo.setPername(permission.getPerBlockurl());
				permissionsVos.add(permissionsVo);
			}
		}
		return permissionsVos;
	}
	/**
	 * 菜单角色的用户详细信息
	 */
	public List<EmpVo> findMenuRoleEmpDesc(Integer roleid) {
		//2.角色所拥有的用户
		Menurole menurole = menuRoleDAO.findByRoleId(roleid);
		List<Emp> emps = menurole.getEmps();
		List<EmpVo> empVos = new ArrayList<>();
		for (Emp emp : emps) {
			EmpVo empVo = new EmpVo();
			empVo.setEmpid(emp.getEmpId());
			empVo.setEmpname(emp.getEmpName());
			empVos.add(empVo);
		}
		return empVos;
	}
}
